//
//  SGScanningQRCodeVC.m
//  SGQRCodeExample
//
//  Created by Sorgle on 16/8/25.
//  Copyright © 2016年 Sorgle. All rights reserved.
//
//  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//
//  - - 如在使用中, 遇到什么问题或者有更好建议者, 请于kingsic@126.com邮箱联系 - - - - - //
//  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  - - GitHub下载地址 https://github.com/kingsic/SGQRCode.git - - - - - - - - - //
//
//  扫一扫

/*
     二维码扫描的步骤：
     1、创建设备会话对象，用来设置设备数据输入
     2、获取摄像头，并且将摄像头对象加入当前会话中
     3、实时获取摄像头原始数据显示在屏幕上
     4、扫描到二维码/条形码数据，通过协议方法回调
 
     AVCaptureSession 会话对象。此类作为硬件设备输入输出信息的桥梁，承担实时获取设备数据的责任
     AVCaptureDeviceInput 设备输入类。这个类用来表示输入数据的硬件设备，配置抽象设备的port
     AVCaptureMetadataOutput 输出类。这个支持二维码、条形码等图像数据的识别
     AVCaptureVideoPreviewLayer 图层类。用来快速呈现摄像头获取的原始数据
     二维码扫描功能的实现步骤是创建好会话对象，用来获取从硬件设备输入的数据，并实时显示在界面上。在扫描到相应图像数据的时候，通过AVCaptureVideoPreviewLayer类型进行返回
 */

#import "SGScanningQRCodeVC.h"
#import <AVFoundation/AVFoundation.h>
#import "SGScanningQRCodeView.h"
//相册
#import "HXCustomNavigationController.h"
#import "HXPhotoManager.h"
//家属账户绑定
//#import "LGPreferenceRelationView.h"
//#import "LGBindingStatusController.h"
/** 扫描内容的Y值 */
#define scanTop     topBarHeight
#define scanBottom  (topBarHeight+viewPix(250))

#define timerDuration  2.5

@interface SGScanningQRCodeVC ()<AVCaptureMetadataOutputObjectsDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate,HXCustomNavigationControllerDelegate>
/** 会话对象 */
@property (nonatomic , strong)AVCaptureSession *session;
/** 图层类 */
@property (nonatomic , strong)AVCaptureVideoPreviewLayer *previewLayer;
@property (nonatomic , strong)SGScanningQRCodeView *scanningView;

/**   */
@property (nonatomic , strong)HXPhotoManager *manager;
/**   */
@property (nonatomic , strong)UIImageView *animationView;
/**   */
@property (nonatomic , strong)UIButton *photoBtn;

@property (nonatomic , assign)BOOL first_push;
/**   */
@property (nonatomic , assign)BOOL stopScan;
/**   */
@property (nonatomic , strong)NSTimer *timer;

@end

@implementation SGScanningQRCodeVC
- (void)viewDidLoad {
    [super viewDidLoad];
    self.fd_prefersNavigationBarHidden = YES;
    [self.backBtn setImage:kNavBackImageWhite forState:UIControlStateNormal];
    self.view.backgroundColor = [UIColor colorWithString:@"#0D0D0D" alpha:0.6];
    [self.view addSubview:self.animationView];
    [self.view addSubview:self.backBtn];
    [self.view addSubview:self.photoBtn];
    self.first_push = YES;
    self.stopScan = NO;
    [self setupScanningQRCode];
    [self animationAction];
//    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

- (HXPhotoManager *)manager {
    if (!_manager) {
        _manager = [[HXPhotoManager alloc] initWithType:HXPhotoManagerSelectedTypePhoto];
        _manager.configuration.requestImageAfterFinishingSelection = YES;
        _manager.configuration.languageType = HXPhotoLanguageTypeSc;
        _manager.configuration.type = HXConfigurationTypeWXChat;
        _manager.configuration.singleSelected = YES;
        _manager.configuration.photoCanEdit = NO;
    }
    return _manager;
}

- (void)animationAction{
    [UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionRepeat animations:^{
        self.animationView.frame = CGRectMake(0, scanBottom, Screen_W, viewPix(180));
    } completion:^(BOOL finished) {
        self.animationView.frame = CGRectMake(0, topBarHeight, Screen_W, viewPix(180));
    }];

}

-(void)backButtonAction{
    [self.navigationController popViewControllerAnimated:YES];
    [self.scanningView removeTimer];
    [self.scanningView removeFromSuperview];
    self.scanningView = nil;
    [self resetNavigationThem];
}

-(void)resetNavigationThem{
    [UIBarButtonItem appearance].tintColor = kNavTitleColor;
    [[UIBarButtonItem appearance] setTitleTextAttributes:
     @{NSForegroundColorAttributeName:kNavTitleColor,
       NSFontAttributeName:kNavTitleFont} forState:UIControlStateNormal];
    [[UINavigationBar appearance] setTranslucent:NO];
    if (@available(iOS 15.0, *)) {
        //适配iOS15
        UINavigationBarAppearance *naviBar = [UINavigationBarAppearance new];
        naviBar.backgroundImage = [UIImage imageWithColor:kNavBgColor];
        naviBar.titleTextAttributes = @{NSForegroundColorAttributeName:kNavTitleColor,
                                        NSFontAttributeName:kNavTitleFont};
        naviBar.shadowImage = [UIImage imageWithColor:[UIColor whiteColor]];
        [[UINavigationBar appearance] setScrollEdgeAppearance:naviBar];
        [[UINavigationBar appearance] setStandardAppearance:naviBar];
    }else{
        
        [[UINavigationBar appearance] setBackgroundColor:kNavBgColor];
        [[UINavigationBar appearance] setBackgroundImage:[UIImage imageWithColor:kNavBgColor] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
        [[UINavigationBar appearance] setTitleTextAttributes:
         @{NSForegroundColorAttributeName:kNavTitleColor,
           NSFontAttributeName:kNavTitleFont}];
    }
}

-(void)boundDoctor:(NSString *)content{
    if (self.stopScan == YES) {
        return;
    }
//    [RequestUtil withPOST:self.action parameters:@{@"userid":kUserId,@"utoken":kToken,@"islogin":kIsLogin,@"content":content} withSign:YES success:^(NSURLSessionDataTask *task, id responseObject) {
//        if ([responseObject[@"code"] isEqualToString:@"200"]) {
//            self.stopScan = YES;
//            NSDictionary * dic = responseObject[@"data"] ;
//            if ([self.delegate respondsToSelector:@selector(sendScanningResult: dic:)]) {
//                [self.delegate sendScanningResult:@"successed" dic:dic];
//                [self.navigationController popViewControllerAnimated:YES];
//            }
//        }else{
//            NSString * msg = responseObject[@"msg"] ;
//            UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"" message:msg preferredStyle:UIAlertControllerStyleAlert];
//            UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
//                [self.scanningView timerContinue];
//            }];
//            [alertController addAction:okAction];
//            [self presentViewController:alertController animated:YES completion:nil];
//        }
//    } failure:^(NSURLSessionDataTask *task, NSError *error) {
//        [self.scanningView timerContinue];
//        [TooltipView showMessage:@"亲，网络不给力啊~" offset:0];
//    }];
}



#pragma mark - - - 二维码扫描
- (void)setupScanningQRCode{
    // 1、获取摄像设备
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    // 2、创建输入流
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
    
    // 3、创建输出流
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    
    // 4、设置代理 在主线程里刷新
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    // 设置扫描范围(每一个取值0～1，以屏幕右上角为坐标原点)
    // 注：微信二维码的扫描范围是整个屏幕， 这里并没有做处理（可不用设置）
//    output.rectOfInterest = CGRectMake(0.05, 0.2, 0.7, 0.6);
    
    // 5、 初始化链接对象（会话对象）
    self.session = [[AVCaptureSession alloc] init];
    // 高质量采集率
    [_session setSessionPreset:AVCaptureSessionPresetHigh];
    
    // 5.1 添加会话输入
    [_session addInput:input];
    
    // 5.2 添加会话输出
    [_session addOutput:output];
    
    // 6、设置输出数据类型，需要将元数据输出添加到会话后，才能指定元数据类型，否则会报错
    // 设置扫码支持的编码格式(如下设置条形码和二维码兼容)
    output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code,  AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
    
    // 7、实例化预览图层, 传递_session是为了告诉图层将来显示什么内容
    self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
    _previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    _previewLayer.frame = self.view.layer.bounds;
    
    // 8、将图层插入当前视图
    [self.view.layer insertSublayer:_previewLayer atIndex:0];
    
    // 9、启动会话
    [_session startRunning];
}

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    // 会频繁的扫描，调用代理方法
    if (self.stopScan == YES) {
        return;
    }
    // 0. 扫描成功之后的提示音
//    [self playSoundEffect:@"sound.caf"];

    // 1. 如果扫描完成，停止会话
//    [self.session stopRunning];
    
    // 2. 删除预览图层
//    [self.previewLayer removeFromSuperlayer];
    
     // 3. 设置界面显示扫描结果
    if (metadataObjects.count > 0) {
        __block AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
//        NSLog(@"metadataObjects = %@", metadataObjects);
        if(self.action == LGScanActionPupillus && self.delegate && [self.delegate respondsToSelector:@selector(scanningContent:)]){
            self.stopScan = YES;
            [self.delegate scanningContent:[ObjectTool jsonToObject:obj.stringValue]];
            [self.navigationController popViewControllerAnimated:YES];
            
        }else if (self.action == LGScanActionFamily){
            //家属账户绑定
            self.stopScan = YES;
//            LGPreferenceRelationView *relationView = [[LGPreferenceRelationView alloc]initWithFrame:CGRectMake(0, 0, Screen_W, Screen_H)];
//            __weak typeof(self)weakSelf = self;
//            relationView.relationViewAction = ^(NSString * _Nonnull content) {
//                if(content.length>0){
//                    //选了角色
//                    NSDictionary *infoDic = [ObjectTool jsonToObject:obj.stringValue];
//                    [RequestUtil bodayPOST:LGLinkUrl1(@"sanofi-adtx-precord/adtxRelation/save") parameters:@{@"userIdCard":kCardId,@"otherIdCard":LGNSString(infoDic[@"idCard"]),@"relationType":content} header:YES success:^(id responseData) {
//                        if([responseData[@"code"] integerValue] == 200){
//                            LGBindingStatusController *controller = [[LGBindingStatusController alloc]init];
//                            controller.type = @"等待验证";
//                            [self.navigationController pushViewController:controller animated:YES];
//                        }
//                        weakSelf.stopScan = NO;
//                    } failure:^(NSError *error) {
//                        weakSelf.stopScan = NO;
//                    }];
//                }
//            };
//            [self.view.window addSubview:relationView];
        }else if ([obj.stringValue hasPrefix:@"http"]) {
            [self boundDoctor:obj.stringValue];
         } else { // 扫描结果为条形码
             UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"" message:@"暂未识别出二维码" preferredStyle:UIAlertControllerStyleAlert];
             UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
             }];
             [alertController addAction:okAction];
             [self presentViewController:alertController animated:YES completion:nil];
        }
    }
}


#pragma mark - - - 扫描提示声
/**
 *  播放完成回调函数
 *
 *  @param soundID    系统声音ID
 *  @param clientData 回调时传递的数据
 */
void soundCompleteCallback(SystemSoundID soundID,void * clientData){
    NSLog(@"播放完成...");
//    [self setupScanningQRCode];
}

/**
 *  播放音效文件
 *
 *  @param name 音频文件名称
 */
- (void)playSoundEffect:(NSString *)name{
    NSString *audioFile = [[NSBundle mainBundle] pathForResource:name ofType:nil];
    NSURL *fileUrl = [NSURL fileURLWithPath:audioFile];
    // 1.获得系统声音ID
    SystemSoundID soundID = 0;
    /**
     * inFileUrl:音频文件url
     * outSystemSoundID:声音id（此函数会将音效文件加入到系统音频服务中并返回一个长整形ID）
     */
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
    
    // 如果需要在播放完之后执行某些操作，可以调用如下方法注册一个播放完成回调函数
    AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL);
    
    // 2.播放音频
    AudioServicesPlaySystemSound(soundID);//播放音效
}



// 移除定时器
//- (void)viewDidDisappear:(BOOL)animated {
//    [super viewDidDisappear:animated];
//    [self.scanningView removeTimer];
//    [self.scanningView removeFromSuperview];
//    self.scanningView = nil;
//    //    NSLog(@" - - -- viewDidAppear");
//}


#pragma mark - - - 从相册中读取照片识别
- (void)photoBtnAction {
    [self.scanningView timerSuspend];
    HXCustomNavigationController *nav = [[HXCustomNavigationController alloc] initWithManager:self.manager delegate:self];
    nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
    nav.modalPresentationCapturesStatusBarAppearance = YES;
    [self presentViewController:nav animated:YES completion:nil];
    
//    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
//        UIImagePickerController *pickController = [[UIImagePickerController alloc]init];
//        pickController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
//        pickController.delegate = self;
//        pickController.allowsEditing = YES;
//        pickController.modalPresentationStyle = UIModalPresentationFullScreen;
//        [self presentViewController:pickController animated:YES completion:nil];
//    }
}

- (void)photoNavigationViewController:(HXCustomNavigationController *)photoNavigationViewController
                       didDoneAllList:(NSArray<HXPhotoModel *> *)allList
                               photos:(NSArray<HXPhotoModel *> *)photoList
                               videos:(NSArray<HXPhotoModel *> *)videoList
                             original:(BOOL)original{
    HXPhotoModel *model = photoList[0];
    
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{ CIDetectorAccuracy : CIDetectorAccuracyHigh }];
    
    // 取得识别结果
    NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:model.previewPhoto.CGImage]];
    
    if (features.count == 0){
        UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"" message:@"暂未识别出二维码" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [self.scanningView timerContinue];
        }];
        [alertController addAction:okAction];
        [self presentViewController:alertController animated:YES completion:nil];

    }else{
        for (int index = 0; index < [features count]; index ++) {
            CIQRCodeFeature *feature = [features objectAtIndex:index];
            NSString *scannedResult = feature.messageString;
//                NSLog(@"result:%@",scannedResult);
            if (self.first_push) {
                if(self.action == LGScanActionPupillus && self.delegate && [self.delegate respondsToSelector:@selector(scanningContent:)]){
                    [self.delegate scanningContent:[ObjectTool jsonToObject:scannedResult]];
                    [self.navigationController popViewControllerAnimated:YES];
                    
                }else if (self.action == LGScanActionFamily){
                    //家属账户绑定
//                    LGPreferenceRelationView *relationView = [[LGPreferenceRelationView alloc]initWithFrame:CGRectMake(0, 0, Screen_W, Screen_H)];
//                    [self.view.window addSubview:relationView];
                } else {
                    UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"" message:@"暂未识别出二维码" preferredStyle:UIAlertControllerStyleAlert];
                    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                        [self.scanningView timerContinue];
                    }];
                    [alertController addAction:okAction];
                    [self presentViewController:alertController animated:YES completion:nil];
                }
            }
        }
    }
}


#pragma mark---相机、相册代理方法
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    UIImage *image = info[@"UIImagePickerControllerEditedImage"];
    [picker dismissViewControllerAnimated:YES completion:^{
        CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{ CIDetectorAccuracy : CIDetectorAccuracyHigh }];
        
        // 取得识别结果
        NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];
        
        if (features.count == 0){
            UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"" message:@"暂未识别出二维码" preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                [self.scanningView timerContinue];
            }];
            [alertController addAction:okAction];
            [self presentViewController:alertController animated:YES completion:nil];

        }else{
            for (int index = 0; index < [features count]; index ++) {
                CIQRCodeFeature *feature = [features objectAtIndex:index];
                NSString *scannedResult = feature.messageString;
//                NSLog(@"result:%@",scannedResult);
                if (self.first_push) {
                    if ([scannedResult hasPrefix:@"http"]) {
                        [self boundDoctor:scannedResult];
                    } else {
                        UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"" message:@"暂未识别出二维码" preferredStyle:UIAlertControllerStyleAlert];
                        UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                            [self.scanningView timerContinue];
                        }];
                        [alertController addAction:okAction];
                        [self presentViewController:alertController animated:YES completion:nil];
                    }
                }
            }
        }
    }];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    [picker dismissViewControllerAnimated:YES completion:nil];
    [self.scanningView timerContinue];
}


-(UIButton *)photoBtn{
    if(!_photoBtn){
        _photoBtn = [UIButton buttonWithTitle:@"相册" titleFont:LGFont(14) textColor:@"#FFFFFF" imageName:@"扫一扫-相册"];
        _photoBtn.frame = CGRectMake((Screen_W-viewPix(100))/2.0, Screen_H-bottomSafeBarHeight/2.0-viewPix(110), viewPix(100), viewPix(90));
        [_photoBtn setButtonInsetsStyle:LGButtonInsetsStyleTop marginSpace:15];
        [_photoBtn addTarget:self action:@selector(photoBtnAction) forControlEvents:UIControlEventTouchUpInside];
    }
    return _photoBtn;
}

-(UIImageView *)animationView{
    if(!_animationView){
        _animationView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"扫一扫-扫描"]];
        _animationView.frame = CGRectMake(0, topBarHeight, Screen_W, viewPix(180));
    }
    return _animationView;
}

-(NSTimer *)timer{
    if(!_timer){
        _timer = [NSTimer scheduledTimerWithTimeInterval:timerDuration target:self selector:@selector(animationAction) userInfo:nil repeats:YES];
    }
    return _timer;
}



@end


